<?php
require __DIR__ . '/vendor/autoload.php';

use GuzzleHttp\Client;
use GuzzleHttp\Cookie\CookieJar;
use GuzzleHttp\Middleware;

// 默认配置
const DEFAULT_CONFIG = [
    'method'          => 'GET',
    'url'             => '',
    'cookies'         => [],
    'query'           => [],
    'json'            => [],
    'body'            => '',
    'formdata'        => '',
    'debug'           => false,
    'multipart'       => [],
    'http_errors'     => true,
    'headers'         => [],
    'timeout'         => 3,
    'connect_timeout' => 1,
    'json_decode'     => true,
    'save_body'       => false,
    'verify'          => false,
];

// 读取文件
$sourcePath = $argv[1];
$sourceDir = dirname($sourcePath);
if (!file_exists($sourcePath)) {
    die('no this file');
}

// 获取配置
$file = file_get_contents($sourcePath);
$input = json_decode($file, true);
if (json_last_error()) {
    die(json_last_error_msg());
}

$defaultConfig = array_merge(DEFAULT_CONFIG, $input);

// 释放变量
extract($defaultConfig);

if (!$url) {
    die('没有请求地址');
}

// 数组body
if ($body && is_array($body)) {
    $json = array_merge($json, $body);
}

// 其他body
if ($body && !is_array($body)) {
    $req['body'] = $body;
}

// 请求配置
$req = [];
$req['query'] = $query;
if ($json) {
    $req['body'] = json_encode($json, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
    $req['headers'] = array_merge([
        'Content-Type' => 'application/json',
    ], $headers);
}

if ($multipart) {
    foreach ($multipart as &$multi) {
        if ($multi['contents'] && file_exists($multi['contents'])) {
            $multi['contents'] = fopen($multi['contents'], 'r');
        }
    }
    $req['multipart'] = $multipart;
}

// headers
if ($headers) {
    $req['headers'] = array_merge($req['headers'] ?? [], $headers);
}

// cookies
$cookiePath = $sourceDir . '/cookie.php';
if (file_exists($cookiePath)) {
    $baseCookie = include_once $cookiePath;
    $cookies = array_merge($baseCookie, $cookies);
}
if ($cookies ?? null) {
    $req['cookies'] = CookieJar::fromArray($cookies, parse_url($url, PHP_URL_HOST));
}

// formData
$formData = $formData ?? null;
if ($formData) {
    $req['form_params'] = $formData;
}

if ($formData || $multipart) {
    if (strtolower($method) == 'get') {
        echo 'GET方法无法发送body';
        echo PHP_EOL;
        exit();
    }
}

// 日志
$client = new Client(['verify' => $verify]);
$clientHandler = $client->getConfig('handler');
$tapMiddleware = Middleware::tap(function ($request) use ($debug) {
    echo 'uri:' . PHP_EOL;
    echo $request->getMethod();
    echo " ";
    echo (string) $request->getUri() . PHP_EOL;
    // echo '---------' . PHP_EOL;
    echo PHP_EOL;
    if (!$debug) {
        echo '---------' . PHP_EOL;
        echo PHP_EOL;
        return;
    }
    echo 'header:' . PHP_EOL;
    $headers = $request->getHeaders();
    foreach ($headers as $name => $value) {
        echo $name . ": " . implode(", ", $value) . PHP_EOL;
    }
    // echo '---------' . PHP_EOL;
    echo PHP_EOL;

    echo 'body:' . PHP_EOL;
    $body = (string) $request->getBody();
    if ($body) {
        echo $body . PHP_EOL;
    }
    echo '---------' . PHP_EOL;
});
$req['handler'] = $tapMiddleware($clientHandler);

// 超时
$req['timeout'] = $timeout;
$req['connect_timeout'] = $connect_timeout;

// 发送请求
$t1 = microtime(true);
try {
    $res = $client->request($method, $url, $req);
    $body = $res->getBody();
    $header = $res->getHeaders();
    $status = $res->getStatusCode() . ' ' . $res->getReasonPhrase();
} catch (\Exception $e) {
    /**
     * @var mixed
     */
    $e = $e;
    $response = $e->getResponse();

    if (!$response) {
        echo $e->getMessage();
        return;
    }

    $body = $response->getBody()->getContents() ?? $e->getMessage();
    $header = $response->getHeaders() ?? [];
    $status = $response->getStatusCode() . ' ' . $response->getReasonPhrase();
}

file_put_contents(__DIR__ . '/body.log', $body);

$t2 = microtime(true);
if ($debug) {
    echo 'status:' . PHP_EOL;
    echo $status . PHP_EOL;
    echo PHP_EOL;

    echo 'header:' . PHP_EOL;
    foreach ($header as $k => $v) {
        echo $k . ':' . implode(';', $v) . PHP_EOL;
    }
    echo PHP_EOL;
}

// 返回了json
if (isset($header['Content-Type'])) {
    if (strpos(implode(',', $header['Content-Type']), 'application/json') !== false && $json_decode == true) {
        $body = json_encode(json_decode($body, true), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT) ?? $body;
    }
}

echo 'response:' . PHP_EOL;
echo $body . PHP_EOL;
echo '---------' . PHP_EOL;
echo 'time:' . PHP_EOL;
echo ($t2 - $t1) . 's';
echo PHP_EOL;
